package com.shungen.apicloud.utils;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTCreator;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTCreationException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;

/**
 * JWT工具类
 * @author shungen
 * @date 2024年07月30日 16:44
 */
public class JWTUtil {
    private static final Logger logger = LoggerFactory.getLogger(JWTUtil.class);

    private static final String SIGNATURE  = System.getenv("JWT_SIGNATURE_KEY"); // 从环境变量读取签名密钥;
//    private static final String SIGNATURE  = "test";
    private static final int DEFAULT_EXPIRE_TIME = 3600; // 默认过期时间为3600秒（1小时）

    private static final Algorithm algorithm;
    private static final JWTVerifier verifier;

    static {
        if (SIGNATURE == null || SIGNATURE.isEmpty()) {
            throw new IllegalArgumentException("JWT_SIGNATURE_KEY environment variable is not set");
        }
        algorithm = Algorithm.HMAC256(SIGNATURE);
        verifier = JWT.require(algorithm).build();
    }

    private JWTUtil() {
        // Private constructor to prevent instantiation
    }

    /**
     * 生成token
     * @param payload 传入payload
     * @param expireTime 过期时间（秒）
     * @return 返回token
     */
    public static String generateToken(Map<String, String> payload, int expireTime) {
        try {
            JWTCreator.Builder builder = JWT.create();
            payload.forEach(builder::withClaim);

            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.SECOND, expireTime > 0 ? expireTime : DEFAULT_EXPIRE_TIME);
            builder.withExpiresAt(calendar.getTime());

            return builder.sign(algorithm);
        } catch (JWTCreationException exception) {
            logger.error("Error creating JWT token", exception);
            return null;
        }
    }

    /**
     * 生成token，使用默认过期时间
     * @param payload 传入payload
     * @return 返回token
     */
    public static String generateToken(Map<String, String> payload) {
        return generateToken(payload, DEFAULT_EXPIRE_TIME);
    }



    /**
     * 获取token中的payload
     * @param token 要解析的token
     * @return 解析后的JWT
     */
    private static DecodedJWT decodeToken(String token) {
        try {
            return verifier.verify(token);
        } catch (JWTVerificationException exception) {
            logger.error("Error decoding JWT token", exception);
            return null;
        }
    }
    /**
     * 验证token
     * @param token 要验证的token
     * @return 验证结果
     */
    public static boolean verifyToken(String token) {
        try {
            verifier.verify(token);
            return true;
        } catch (JWTVerificationException exception) {
            logger.error("Invalid JWT token", exception);
            return false;
        }
    }

    /**
     * 从token中获取指定的claim
     * @param token 要解析的token
     * @param claimName 要获取的claim名称
     * @return claim的值
     */
    public static String getClaimFromToken(String token, String claimName) {
        try {
            DecodedJWT decodedJWT = verifier.verify(token);
            return decodedJWT.getClaim(claimName).asString();
        } catch (JWTVerificationException exception) {
            logger.error("Error getting claim from JWT token", exception);
            return null;
        }
    }

    public static void main(String[] args) {
        HashMap<String,String> userMap = new HashMap<>();
        userMap.put("id","1001");
        userMap.put("role","user");
        String token = JWTUtil.generateToken(userMap, 1);
        System.out.println("服务端生成的token:" + token);
        String claimFromToken = JWTUtil.getClaimFromToken(token, "id");
        System.out.println("解析出来的用户id:" + claimFromToken);
    }
}